﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Evaluation;
using MMOShared;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using System.Drawing;
using System.IO;
using Microsoft.Build.Construction;
using System.Windows.Forms;

namespace MMOResCreator
{
    public enum ResourceType
    {
        RES_TEXTURE,
        RES_FONT,
        RES_MODEL,
        RES_EFFECT,
        RES_OTHER
    };

    public class CompileSettings
    {
        public bool TextureGenerateMipmaps { get; set; }
        public bool ResizeToPowerOfTwo { get; set; }
        public TextureProcessorOutputFormat TextureFormat { get; set; }
        public Color ColorKeyColor { get; set; }
        public bool ColorKeyEnabled { get; set; }
        public bool ModelGenerateMipmaps { get; set; }
        public bool GenerateTangentFrames { get; set; }
        public bool ResizeTexturesToPowerOfTwo { get; set; }
        public float Scale { get; set; }
        public bool SwapWindingOrder { get; set; }
        public TextureProcessorOutputFormat ModelTextureFormat { get; set; }
        public float RotationX { get; set; }
        public float RotationY { get; set; }
        public float RotationZ { get; set; }

        public CompileSettings()
        {
        }
        public static CompileSettings DefaultValues()
        {
            CompileSettings comp = new CompileSettings();
            comp.TextureGenerateMipmaps = false;
            comp.ResizeToPowerOfTwo = false;
            comp.TextureFormat = TextureProcessorOutputFormat.Color;
            comp.ColorKeyColor = Color.FromArgb(255, 255, 0, 255);
            comp.ColorKeyEnabled = true;
            comp.ModelGenerateMipmaps = true;
            comp.GenerateTangentFrames = false;
            comp.ResizeTexturesToPowerOfTwo = false;
            comp.Scale = 1.0f;
            comp.SwapWindingOrder = false;
            comp.ModelTextureFormat = TextureProcessorOutputFormat.DxtCompressed;
            comp.RotationX = 0.0f;
            comp.RotationY = 0.0f;
            comp.RotationZ = 0.0f;
            return comp;
        }
    }

    public class CompileResourceEntry
    {
        public ResourceEntry BaseEntry { get; private set; }
        public ResourceType ResourceType { get; private set; }
        public string ContentProcessor { get; private set; }
        public string ContentImporter { get; private set; }
        public CompileSettings CompileSettings { get; private set; }
        public CompileResourceEntry(ResourceEntry baseE, UInt16 version )
        {
            this.BaseEntry = baseE;
            this.CompileSettings = CompileSettings.DefaultValues();
            CalculateFileTypeAndContentWorkers(this, version);
        }

        public static ResourceType GetResourceType(string file)
        {
            if (File.Exists(file))
            {
                string ext = Path.GetExtension(file);

                string texExts = ".bmp .jpg .png .tga .dds";
                string fontExts = ".spritefont";
                string modelExts = ".fbx .x";
                string effectExts = ".fx";

                if (texExts.Contains(ext))
                {
                    return ResourceType.RES_TEXTURE;
                }
                else if (fontExts.Contains(ext))
                {
                    return ResourceType.RES_FONT;
                }
                else if (modelExts.Contains(ext))
                {
                    return ResourceType.RES_MODEL;
                }
                else if (effectExts.Contains(ext))
                {
                    return ResourceType.RES_EFFECT;
                }
            }
            return ResourceType.RES_OTHER;
        }

        private void CalculateFileTypeAndContentWorkers(CompileResourceEntry entry, UInt16 version )
        {
            string path = entry.BaseEntry.RelativePath;
            if (File.Exists("Updates\\"+version+"\\"+path))
            {
                string ext = Path.GetExtension(path);

                string texExts = ".bmp .jpg .png .tga .dds";
                string fontExts = ".spritefont";
                string modelExts = ".fbx .x";
                string effectExts = ".fx";

                string filePath = "Updates\\" + version + "\\" + entry.BaseEntry.RelativePath;

                if (texExts.Contains(ext))
                {
                    entry.ResourceType = ResourceType.RES_TEXTURE;
                    entry.ContentProcessor = "TextureProcessor";
                    entry.ContentImporter = "TextureImporter";

                    /*Item.SetMetadataValue("ProcessorParameters_GenerateMipmaps", CompileSettings.TextureGenerateMipmaps.ToString());
                    Item.SetMetadataValue("ProcessorParameters_ResizeToPowerOfTwo", CompileSettings.ResizeToPowerOfTwo.ToString());
                    Item.SetMetadataValue("ProcessorParameters_TextureFormat", CompileSettings.TextureFormat.ToString());*/
                }
                else if (fontExts.Contains(ext))
                {
                    entry.ResourceType = ResourceType.RES_FONT;
                    entry.ContentProcessor = "FontDescriptionProcessor";
                    entry.ContentImporter = "FontDescriptionImporter";
                }
                else if (modelExts.Contains(ext))
                {
                    entry.ResourceType = ResourceType.RES_MODEL;
                    entry.ContentProcessor = "ModelProcessor";
                    entry.ContentImporter = null;

                    /*Item.SetMetadataValue("ProcessorParameters_ColorKeyColor", CompileSettings.ColorKeyColor.R + ", " + CompileSettings.ColorKeyColor.G + ", " + CompileSettings.ColorKeyColor.B + ", " + CompileSettings.ColorKeyColor.A);
                    Item.SetMetadataValue("ProcessorParameters_ColorKeyEnabled", CompileSettings.ColorKeyEnabled.ToString());
                    Item.SetMetadataValue("ProcessorParameters_GenerateMipmaps", CompileSettings.ModelGenerateMipmaps.ToString());
                    Item.SetMetadataValue("ProcessorParameters_GenerateTangentFrames", CompileSettings.GenerateTangentFrames.ToString());
                    Item.SetMetadataValue("ProcessorParameters_ResizeTexturesToPowerOfTwo", CompileSettings.ResizeTexturesToPowerOfTwo.ToString());
                    Item.SetMetadataValue("ProcessorParameters_Scale", CompileSettings.Scale.ToString());
                    Item.SetMetadataValue("ProcessorParameters_SwapWindingOrder", CompileSettings.SwapWindingOrder.ToString());
                    Item.SetMetadataValue("ProcessorParameters_TextureFormat", CompileSettings.ModelTextureFormat.ToString());
                    Item.SetMetadataValue("ProcessorParameters_RotationX", CompileSettings.RotationX.ToString());
                    Item.SetMetadataValue("ProcessorParameters_RotationY", CompileSettings.RotationY.ToString());
                    Item.SetMetadataValue("ProcessorParameters_RotationZ", CompileSettings.RotationZ.ToString());*/
                }
                else if (effectExts.Contains(ext))
                {
                    entry.ResourceType = ResourceType.RES_EFFECT;
                    entry.ContentProcessor = "EffectProcessor";
                    entry.ContentImporter = "EffectImporter";
                }
                else
                {
                    entry.ResourceType = ResourceType.RES_OTHER;
                    entry.ContentProcessor = null;
                    entry.ContentImporter = null;
                }
                //if (entry.ContentImporter != null)
                    //Item.SetMetadataValue("Importer", entry.ContentImporter);
                //if (entry.ContentProcessor != null)
                    //Item.SetMetadataValue("Processor", entry.ContentProcessor);
            }
        }
        public string[] getAsViewItem()
        {
            string[] ret = { 
                                 this.BaseEntry.ResourceID,
                                 this.BaseEntry.RelativePath,
                                 this.ResourceType.ToString(),
                                 this.ContentProcessor == null ? "None" : this.ContentProcessor,
                                 this.ContentImporter == null ? "None" : this.ContentImporter 
                               };
            return ret;
        }
    }

    /*
     * Content compiler
     */
    public class ContentCompiler
    {
        private Project project;
        public List<CompileResourceEntry> CompilationFiles { get; private set; }
        private string projectPath;
        private UInt16 currV;
        private string savePath;
        private string projXML;

        public ContentCompiler(UInt16 versionToCompile,string savePath) {            
            StreamReader projFile = File.OpenText(@"content_project_base.txt");
            projXML = projFile.ReadToEnd();
            projFile.Close();

            //project;
            

            currV = versionToCompile;
            this.savePath = savePath;
        }

        public void SetProjectPath(string path) { projectPath = path; }

        public void Compile()
        {
            string itemsXML = "";
            /*<!--<Compile Include="t.bmp">
      <Name>t</Name>
      <Importer>TextureImporter</Importer>
      <Processor>TextureProcessor</Processor>
    </Compile>-->*/
            foreach(CompileResourceEntry entr in CompilationFiles){
                string itemXML = "\t\t<Compile Include=\"" + entr.BaseEntry.RelativePath + "\">\n" +
                    "\t\t\t<Name>" + entr.BaseEntry.ResourceID + "</Name>\n" +
                    "\t\t\t<Importer>" + entr.ContentImporter + "</Importer>\n" +
                    "\t\t\t<Processor>" + entr.ContentProcessor + "</Processor>\n" +
                    "\t\t</Compile>";
                itemsXML += itemXML;
            }
            //Insert compile items into xml
            projXML = projXML.Replace("$$ITEMS$$", itemsXML);

            MessageBox.Show(itemsXML);

            //write xml to project file
            //StreamWriter projFile = new StreamWriter("Content.proj",false);
            //projFile.Write(projXML);
            //projFile.Close();

            //load up project and build
            project = new Project(@"MMOTestContent.contentproj");//"Content.proj");
            ContentCompileLogger log = new ContentCompileLogger();
            project.Build(log);
        }

        public void SetEntriesToCompile(List<ResourceEntry> files)
        {
            CompilationFiles = new List<CompileResourceEntry>();
            foreach (ResourceEntry e in files)
            {
                CompilationFiles.Add(new CompileResourceEntry(e,currV));
            }
        }
    }
}
